package com.lengyu.iottransfer.gateway.config;

import com.alibaba.fastjson.JSONObject;
import com.lengyu.iottransfer.gateway.common.ByteUtils;
import com.lengyu.iottransfer.gateway.service.impl.ElecLcdTransferService;
import com.lengyu.iottransfer.gateway.service.impl.ZhengqiF2001XTransferService;
import com.lengyu.iottransfer.gateway.tcp.daxiang.DaxiangGuanpianTransfer;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;

import java.util.Arrays;

@Configuration
public class MqttConfig {

    private final static String clientId = "iot_transfer";

    private final static Logger logger = LoggerFactory.getLogger(MqttConfig.class);

//    private final  static String  mqtt_addr= "tcp://58.241.13.10:1883";
    private final  static String  mqtt_addr= "tcp://172.2.0.28:1883";

    @Autowired
    ElecLcdTransferService elecLcdTransferService;

    @Autowired
    ZhengqiF2001XTransferService zhengqiF2001XTransferService;

    @Autowired
    DaxiangGuanpianTransfer daxiangGuanpianTransfer;

    /**
     * 连接mqtt服务器的工厂
     * @return
     */
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        options.setServerURIs(new String[] { mqtt_addr });
        options.setUserName("iot_transfer");
        options.setPassword("tjgk_xinxishi".toCharArray());
        factory.setConnectionOptions(options);
        return factory;
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel") //inputChannel的名字必须和上面的MessageChannel的方法名保持一致
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(clientId + "_outbound" + System.currentTimeMillis(), mqttClientFactory());
        messageHandler.setAsync(true);
        return messageHandler;
    }

    /**
     * 收消息的通道，注意实际开发中和发的可能不在一起
     * @return
     */
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }


    /**
     * 收消息的通道，注意实际开发中和发的可能不在一起
     * @return
     */
    @Bean
    public MessageChannel mqttInputChannelForString() {
        return new DirectChannel();
    }

    @Bean
    public MessageProducer inbound() {
        // 设置转换器，接收bytes
        DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
        converter.setPayloadAsBytes(true);

        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(mqtt_addr, clientId+ "_inbound" + System.currentTimeMillis(),
                        "/user_iot/#");
        adapter.setCompletionTimeout(5000);
//        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setConverter(converter);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    @Bean
    public MessageProducer inbound2() {
        // 设置转换器，接收bytes
//        DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
//        converter.setPayloadAsBytes(true);

        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(mqtt_addr, clientId+ "service_call_inbound" + System.currentTimeMillis(),
                        "/lengyu_iot/service/call/#");
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
//        adapter.setConverter(converter);
        adapter.setOutputChannel(mqttInputChannelForString());
        return adapter;
    }

    /**
     * 收消息的处理器，用于如何处理消息
     * mqttInputChannel 代表的是收消息的通道对象的id
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannelForString")
    public MessageHandler handlerForString() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                try{

                    String topic = message.getHeaders().get("mqtt_receivedTopic").toString();
                    logger.info("命令下发mqtttopic：" + topic);
                    logger.info("命令下发mqttpayload：" + message.getPayload());
                    if(topic.startsWith("/lengyu_iot/service/call/")){
                        if(topic.endsWith("1f421904c7e2e08f56b890af282c3a20")){
                            logger.info("预埋传感器下行命令a：" + message.getPayload());
                            daxiangGuanpianTransfer.sendCommandToDevice(JSONObject.parseObject(message.getPayload().toString()));
                        }
                    }
                }
                catch(Exception ex){
                    logger.error("err",ex);
                }
            }
        };
    }

    /**
     * 收消息的处理器，用于如何处理消息
     * mqttInputChannel 代表的是收消息的通道对象的id
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                try{
                    // 如果不设置转换器这里强转byte[]会报错
                    byte[] payLoad = (byte[])message.getPayload();

                    String hexString =  ByteUtils.byteArrayToHexString(payLoad);
                    String topic = message.getHeaders().get("mqtt_receivedTopic").toString();

                    //接收的信息不是发送命令，则进行解析
                    if(topic.startsWith("/user_iot") && topic.endsWith("/send")){
                        logger.info("接收消息 topic:" + topic);
                        logger.info("byteArray:" +  Arrays.toString(payLoad));
                        logger.info("HexStr:" + hexString);
                        //有人模块发送的消息
                        if(!hexString.equals("01 03 10 3d 00 04 d1 05")){
                            elecLcdTransferService.decodeData(payLoad,message.getHeaders().get("mqtt_receivedTopic").toString());
                        }
                    }
                    //接收的信息不是发送命令，则进行解析
                    else if(topic.startsWith("/user_iot") && topic.endsWith("/send/F2001XA3L1C4R2PWAL1VAC")){
                        //铁建工科 气表流量计
                        logger.info("接收消息蒸汽表消息 topic:" + topic);
                        logger.info("byteArray:" +  Arrays.toString(payLoad));
                        logger.info("HexStr:" + hexString);
                        zhengqiF2001XTransferService.decodeData(payLoad,message.getHeaders().get("mqtt_receivedTopic").toString());
                    }
                }
                catch(Exception ex){
                    logger.error("err",ex);
                }
            }
        };
    }

}
